package com.longrise.android.upload_offline.synchron;

import android.content.Context;
import android.database.Cursor;
import android.os.Handler;
import android.os.Message;

import com.longrise.LEAP.Base.IO.JSONSerializer;
import com.longrise.LEAP.Base.Objects.EntityBean;
import com.longrise.android.byjk.common.SituationControl;
import com.longrise.android.byjk.common.UrlConstants;
import com.longrise.android.byjk.utils.CourseKeyUtil;
import com.longrise.android.byjk.utils.EncryptDecryptData;
import com.longrise.common.datasource.remote.LoadDataManager;
import com.longrise.common.utils.NetUtil;
import com.longrise.android.upload_offline.DBDAO;

import java.util.ArrayList;
import java.util.List;


/**
 * Created by sujizhong on 16/3/2.
 * 没有网络的情况下 将数据通过数据库进行存储
 * 监听系统网络状况，当接入网络后，查询数据库将数据同步到server端
 */
public class SyncUpLoad {

    private static SyncUpLoad mSyncUpLoad = null;

    public static final List<SyncEntity> mSyncEntities = new ArrayList<>();
    private OnUploadStudyInterface mOnUploadStudyInterface = null;

    //当前队列总长度
    private int mSyncTotal = 0;

    //延时时间
    private final int SLEEP_TIME = 5000;

    private final int MSG_PARALLLEL = 0x00000003;
    private final int MSG_QUERY_SUCCESS = 0x00000004;
    private final int MSG_INSERT_SUCESS = 0x00000005;
    private final int MSG_CALL_BACK = 0x00000006;

    //当前记录失败次数
    private int mERROR = 0;
    //单条记录最大失败次数 包括第一次   默认1次
    private int mMAX_ERROR = 0;
    private static Context mContext;

    private boolean mIsUploadSucess = false;

    private SyncUpLoad() {
    }

    public static SyncUpLoad getInstance(Context context) {
        if (mSyncUpLoad == null) {
            synchronized (SyncUpLoad.class) {
                if (mSyncUpLoad == null) {
                    mSyncUpLoad = new SyncUpLoad();
                }
            }
            mContext = context;
        }
        return mSyncUpLoad;
    }

    public Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_PARALLLEL:
                    if (mERROR < mMAX_ERROR) {
                        try {
                            httpUpload();
                        } catch (Exception e) {
                            e.printStackTrace();
                            mIsUploadSucess = false;
                            sendMsg(MSG_CALL_BACK);
                        }
                    } else {
                        clear();
                    }
                    break;

                case MSG_QUERY_SUCCESS:
                    try {
                        upLoadDataSync();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                case MSG_INSERT_SUCESS:
                    close();
                    break;

                case MSG_CALL_BACK:
                    uploadCallback();
                    break;

                default:
                    break;
            }
        }
    };

    /**
     * 无任何网络状态下，插入数据库
     */
    public void insertDataBaseSyncHron(String... value) throws Exception {
        ID_QueryDataBaseSyncHron(value);
    }

    /**
     * 判断数据库是否存在该字段
     */
    public void ID_QueryDataBaseSyncHron(final String... value) throws Exception {
        new Thread() {
            @Override
            public void run() {
                replace(value);
            }
        }.start();
    }

    private synchronized void replace(String... id) {
        Cursor cursor = null;
        try {
            cursor = DBDAO.getInstance().ID_Query(id[1]);
            if (cursor != null && cursor.getCount() <= 0) {
                DBDAO.getInstance().insert(id[0], id[1], id[2], id[3]);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
            Message msg = new Message();
            msg.what = MSG_INSERT_SUCESS;
            mHandler.sendMessage(msg);
        }
    }

    /**
     * 查询所有记录
     */
    public void queryDataBaseSyncHron(OnUploadStudyInterface onUploadStudyInterface) {
        //用于确认本次查询结果是否全部执行完毕
        if (mSyncTotal != 0) {
            return;
        }
        this.mOnUploadStudyInterface = onUploadStudyInterface;
        new Thread() {
            @Override
            public void run() {
                synchronized (SyncUpLoad.class) {
                    Cursor cursor = null;
                    try {
                        cursor = DBDAO.getInstance().query();
                        if (cursor != null && cursor.getCount() > 0) {
                            mSyncEntities.clear();
                            cursor.moveToFirst();
                            cursor.moveToPrevious();
                            while (cursor.moveToNext()) {
                                SyncEntity dbEntity = new SyncEntity();
                                String expiretime = cursor.getString(cursor.getColumnIndex(VideoDB.EXOIRETIME));
                                String id = cursor.getString(cursor.getColumnIndex(VideoDB.ID));
                                String studentno = cursor.getString(cursor.getColumnIndex(VideoDB.STUDENTNO));
                                String effecttime = cursor.getString(cursor.getColumnIndex(VideoDB.EFFECTTIME));
                                dbEntity.expiretime = expiretime;
                                dbEntity.id = id;
                                dbEntity.studentno = studentno;
                                dbEntity.effecttime = effecttime;
                                mSyncEntities.add(dbEntity);
                            }
                            sendMsg(MSG_QUERY_SUCCESS);
                        } else {
                            mIsUploadSucess = false;
                            sendMsg(MSG_CALL_BACK);
                        }
                    } catch (Exception e) {
                        mIsUploadSucess = false;
                        sendMsg(MSG_CALL_BACK);
                        e.printStackTrace();
                    } finally {
                        if (cursor != null) {
                            cursor.close();
                        }
                    }
                }
            }
        }.start();
    }

    /**
     * 同步成功后删除该条记录
     */
    public void deleteDataBaseSyncHron() {
        try {
            DBDAO.getInstance().delete_All();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void close() {
        DBDAO.getInstance().close();
    }

    public void setMaxOnErrorSize(int maxSize) {
        this.mMAX_ERROR = maxSize;
    }

    private synchronized void upLoadDataSync() throws Exception {
        mSyncTotal = mSyncEntities.size();
        if (mSyncTotal <= 0) {
            mIsUploadSucess = false;
            sendMsg(MSG_CALL_BACK);
            clear();
        } else {
            httpUpload();
        }
    }

    /**
     * 在onSucess（）方法中循环执行该方法,如果同步成功删除该条记录
     */
    private void httpUpload() throws Exception {
        if (mSyncTotal > 0) {
            EntityBean[] studyrecords = new EntityBean[mSyncTotal];
            String localHostIp = NetUtil.getLocalHostIp();
            for (int i = 0; i < mSyncTotal; i++) {
                SyncEntity dbEntity = mSyncEntities.get(i);
                EntityBean itemBean = new EntityBean();
                itemBean.set("stuclientip", localHostIp);
                itemBean.set("stuclientmacinfo", "androidapp");
                itemBean.set("id", dbEntity.id);  //学习记录id
                itemBean.set("studentno", dbEntity.studentno);//学号
                itemBean.set("effecttime", Double.parseDouble(dbEntity.effecttime));//有效时常
                itemBean.set("expiretime", dbEntity.expiretime);
                studyrecords[i] = itemBean;
            }
            EntityBean bean = new EntityBean();
            bean.set("studyrecords", studyrecords);
            EntityBean reqBean = new EntityBean();
            reqBean.set("bean", bean);

//------以下是增加的加密部分 xkj------------------------
            SyncEntity dbEntity = mSyncEntities.get(0);
            String studyid = dbEntity.id;
            char[] studyidchars = studyid.toCharArray();
            StringBuilder builder = new StringBuilder();
            builder.append(studyidchars[16]);
            builder.append(studyidchars[12]);
            builder.append(studyidchars[16]);
            builder.append(studyidchars[20]);
            builder.append(studyidchars[28]);
            builder.append(studyidchars[2]);
            builder.append(studyidchars[10]);
            builder.append(studyidchars[5]);
            String key1 = builder.toString();
            String serializebean1 = JSONSerializer.getInstance().Serialize(bean);
            String encryptbean1 = null;
            try {
                encryptbean1 = EncryptDecryptData.desEncrypt(serializebean1, key1);
            } catch (Exception e) {
                e.printStackTrace();
            }

            EntityBean fbean2 = new EntityBean();
            fbean2.set("uuid", studyid);
            fbean2.set("data", encryptbean1);
            //需要rsa加密的话就打开
            //fbean2.set("keycode", CourseEncryptionUtil.courseEncrypty(mContext,studyid));

            String serialize2 = JSONSerializer.getInstance().Serialize(fbean2);
           // String key2 = new DESKeyUtils().getbbCourseKeyFromC(mContext);
            String key2 = CourseKeyUtil.getbbCourseKeyFromC(mContext);
            String encryptbean2 = null;
            try {
                encryptbean2 = EncryptDecryptData.desEncrypt(serialize2, key2);
            } catch (Exception e) {
                e.printStackTrace();
            }
            EntityBean fbean3 = new EntityBean();
            fbean3.set("bean", encryptbean2);

            EntityBean fbean4 = new EntityBean();
            fbean4.set("bean", fbean3);
//------以上是增加的加密部分 xkj------------------------

            //离线同步时，实际不检查视频锁时调用接口改为 bbt_course_uStudyRecord_offline   原：bbt_course_uStudyRecord
            //bbt_course_uStudyRecord_offline
            LoadDataManager.getInstance().callService(null, UrlConstants.BaseUrl, "bbt_course_uStudyRecord_offlineByAndroid", fbean4, new LoadDataManager.OnRequestCallListener() {
                @Override
                public void onSuccess(String key, String service, Object result) {
                    EntityBean bean = (EntityBean) result;
                    int resultstate = bean.getInt("resultstate");
                    if (resultstate == 1) {
                        EntityBean resultbean = bean.getBean("result");
                        if (resultbean != null) {
                            int state = resultbean.getInt("state");
                            if (state == 1) {//只有server通知成功才会删除
                                try {
                                    deleteDataBaseSyncHron();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                                SituationControl.onDealSiuationLfViewCallBackRe(true);
                                mIsUploadSucess = true;
                            }
                        }
                    }
                    parseResult(1);  //直接clear   本次执行结束
                }

                @Override
                public void onError(String key, String service, Throwable ex, boolean isOnCallback) {
                    parseResult(1); //直接clear parseReault(0) //如果失败在执行一次   本次执行结束
                    mIsUploadSucess = false;
                }

                @Override
                public void onFinished(String key, String service) {
                    //无论本次请求成功失败都去调用
                    sendMsg(MSG_CALL_BACK);
                }
            });
        } else {
            mIsUploadSucess = false;
            sendMsg(MSG_CALL_BACK);
            clear();
        }
    }

    /**
     * 如果执行失败执行调用该方法  单条记录最大失败次数取决于mMAX_ERROR
     */
    private void parseResult(int resultstate) {
        if (resultstate == 1) {
            clear();
        } else {
            mERROR++;
            Message msg = new Message();
            msg.what = MSG_PARALLLEL;
            mHandler.sendMessageDelayed(msg, SLEEP_TIME);
        }
    }

    /**
     * 执行完该任务统一关闭数据库
     */
    private void clear() {
        try {
            mIsUploadSucess = false;
            if (mSyncEntities != null) {
                mSyncEntities.clear();
                mSyncTotal = 0;
                close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public interface OnUploadStudyInterface {
        void onUploaded(boolean isUpload);
    }

    private void uploadCallback() {
        if (mOnUploadStudyInterface != null) {
            mOnUploadStudyInterface.onUploaded(mIsUploadSucess);
        }
    }

    private void sendMsg(int message) {
        Message msg = new Message();
        msg.what = message;
        mHandler.sendMessage(msg);
    }
}
